import mqtt from 'mqtt'

// MQTT接口定义
export interface AppInfoResponse {
  code: number
  msg: string
  appName: string
  appVersion: string
}

export interface AppInfoRequest {
  request: number
}

export interface WarnStatusResponse {
  code: number
  msg: string
  data: Array<{
    time: string
    identification: string
    content: string
  }>
}

export interface WarnStatusRequest {
  request: number
}

// MQTT主题配置
export interface MQTTTopics {
  APP_INFO_REQUEST: string
  APP_INFO_RESPONSE: string
  WARN_STATUS_REQUEST: string
  WARN_STATUS_RESPONSE: string
}

// MQTT配置接口
export interface MQTTConfig {
  brokerUrl: string
  username: string
  password: string
  clientId: string
  topics: MQTTTopics
  connection: {
    connectTimeout: number
    keepalive: number
    maxReconnectAttempts: number
    reconnectInterval: number
  }
}

// 默认MQTT配置
export const DEFAULT_MQTT_CONFIG: MQTTConfig = {
  brokerUrl: 'mqtt://127.0.0.1:1883',
  username: 'dpin',
  password: '!#%&2468dpin',
  clientId: 'acts-benchmaster',
  topics: {
    APP_INFO_REQUEST: 'appInfo/request',
    APP_INFO_RESPONSE: 'appInfo/response',
    WARN_STATUS_REQUEST: 'warnStatus/request',
    WARN_STATUS_RESPONSE: 'warnStatusData'
  },
  connection: {
    connectTimeout: 10000,
    keepalive: 60,
    maxReconnectAttempts: 5,
    reconnectInterval: 5000
  }
}

// MQTT客户端类
export class MQTTClient {
  private client: mqtt.MqttClient | null = null
  private isConnected = false
  private reconnectAttempts = 0
  private config: MQTTConfig

  constructor(config: MQTTConfig) {
    this.config = config
  }

  // 连接MQTT服务器
  async connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      const options: mqtt.IClientOptions = {
        clientId: this.config.clientId,
        username: this.config.username,
        password: this.config.password,
        clean: true,
        reconnectPeriod: 0, // 禁用自动重连，手动处理
        connectTimeout: this.config.connection.connectTimeout,
        keepalive: this.config.connection.keepalive
      }

      this.client = mqtt.connect(this.config.brokerUrl, options)

      // 连接成功
      this.client.on('connect', () => {
        console.log('MQTT客户端已连接')
        this.isConnected = true
        this.reconnectAttempts = 0
        resolve()
      })

      // 连接错误
      this.client.on('error', (error) => {
        console.error('MQTT连接错误:', error)
        this.isConnected = false
        reject(error)
      })

      // 连接关闭
      this.client.on('close', () => {
        console.log('MQTT连接已关闭')
        this.isConnected = false
        this.handleReconnect()
      })
    })
  }

  // 处理重连
  private handleReconnect(): void {
    if (this.reconnectAttempts < this.config.connection.maxReconnectAttempts) {
      this.reconnectAttempts++
      console.log(`尝试重连 ${this.reconnectAttempts}/${this.config.connection.maxReconnectAttempts}`)
      
      setTimeout(() => {
        if (this.client) {
          this.connect().catch((error) => {
            console.error('重连失败:', error)
          })
        }
      }, this.config.connection.reconnectInterval)
    } else {
      console.error('达到最大重连次数，停止重连')
      this.isConnected = false
    }
  }

  // 订阅主题
  subscribe<T = AppInfoResponse>(topic: string, callback: (message: T) => void): void {
    if (!this.client || !this.isConnected) {
      console.error('MQTT客户端未连接')
      return
    }

    this.client.subscribe(topic, (error) => {
      if (error) {
        console.error(`订阅主题 ${topic} 失败:`, error)
      } else {
        console.log(`已订阅主题: ${topic}`)
      }
    })

    this.client.on('message', (receivedTopic, message) => {
      if (receivedTopic === topic) {
        try {
          const messageStr = message.toString().trim()
          console.log(`收到消息 [${topic}]:`, messageStr)
          
          // 检查消息是否为空
          if (!messageStr) {
            console.warn('收到空消息，跳过解析')
            return
          }
          
          const parsedMessage = JSON.parse(messageStr) as T
          callback(parsedMessage)
        } catch (error) {
          console.error('解析消息失败:', error)
          console.error('原始消息:', message.toString())
        }
      }
    })
  }

  // 发布消息
  publish<T = AppInfoResponse>(topic: string, message: T): void {
    if (!this.client || !this.isConnected) {
      console.error('MQTT客户端未连接')
      return
    }

    const messageString = typeof message === 'string' ? message : JSON.stringify(message)
    
    this.client.publish(topic, messageString, (error) => {
      if (error) {
        console.error(`发布消息到主题 ${topic} 失败:`, error)
      } else {
        console.log(`消息已发布到主题: ${topic}`)
      }
    })
  }

  // 请求应用信息
  requestAppInfo(): void {
    const request: AppInfoRequest = {
      request: 1
    }
    this.publish<AppInfoRequest>(this.config.topics.APP_INFO_REQUEST, request)
  }

  // 请求警告状态数据
  requestWarnStatus(): void {
    const request: WarnStatusRequest = {
      request: 1
    }
    this.publish<WarnStatusRequest>(this.config.topics.WARN_STATUS_REQUEST, request)
  }

  // 断开连接
  disconnect(): void {
    if (this.client) {
      this.client.end()
      this.client = null
      this.isConnected = false
      console.log('MQTT客户端已断开连接')
    }
  }

  // 获取连接状态
  getConnectionStatus(): boolean {
    return this.isConnected
  }

  // 检查是否正在重连
  isReconnecting(): boolean {
    return this.reconnectAttempts > 0 && this.reconnectAttempts < this.config.connection.maxReconnectAttempts
  }

  // 获取重连尝试次数
  getReconnectAttempts(): number {
    return this.reconnectAttempts
  }
}
